package com.zmj.sy.mom.srv.aps.service;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.zmj.sy.mom.srv.aps.bean.entity.resource.LogApi;
import com.zmj.sy.mom.srv.aps.bean.vo.base.BaseIdReqVo;
import com.zmj.sy.mom.srv.aps.bean.vo.base.BasePageResVo;
import com.zmj.sy.mom.srv.aps.bean.vo.logapi.*;
import com.zmj.sy.mom.srv.aps.mapper.LogApiMapper;
import com.zmj.sy.mom.srv.aps.utils.JsonUtils;
import com.zmj.sy.mom.srv.aps.utils.MkHttpUtils;
import com.zmj.sy.mom.srv.aps.utils.SyExceptionUtils;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringEscapeUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.io.File;
import java.util.List;
import java.util.function.BiConsumer;

@RequiredArgsConstructor
@Service
public class LogApiService {

    private final LogApiMapper logApiMapper;
    private final MkHttpUtils mkHttpUtils;
    private final ObjectMapper objectMapper;

    @Value("${spring.cloud.nacos.config.namespace}")
    private String namespace;

    @Value("${project.feign.qms-url}")
    private String qmsUrl;

    private BiConsumer<LogApi, String> consumer = (LogApi logApi, String body)->{
        JsonNode jsonNode = JsonUtils.readTree(body);
        if (jsonNode.get("code").intValue() == 0) {
            logApi.setSuccess(true);
        } else {
            logApi.setSuccess(false);
            logApi.setErrorMsg(jsonNode.get("message").asText());
        }
    };

    @SneakyThrows
    public LogApiDetailResVo detail(BaseIdReqVo reqVo) {

        LogApi logApi = logApiMapper.selectById(reqVo.getId());

        LogApiDetailResVo res = new LogApiDetailResVo();


        if(StringUtils.hasText(logApi.getRequestPath())){
            File file = new File(logApi.getRequestPath());
            if (!file.exists()) {
                throw SyExceptionUtils.e("未找到该日志的请求报文");
            } else {
                res.setRequestBody(FileUtils.readFileToString(new File(logApi.getRequestPath())));

            }
        }

        if(StringUtils.hasText(logApi.getResponsePath())){
            File file = new File(logApi.getResponsePath());
            if (!file.exists()) {
                throw SyExceptionUtils.e("未找到该日志的请求报文");
            } else {
                res.setResponseBody(FileUtils.readFileToString(new File(logApi.getResponsePath())));
                res.setResponseBody(StringEscapeUtils.unescapeJava(res.getResponseBody()));
            }
        }

        return res;
    }

    public BasePageResVo<LogApiListResVo> list(LogApiListReqVo reqVo) {

        Page<LogApi> page = logApiMapper.lambdaQuery()
                .eq(StringUtils.hasText(reqVo.getAppId()), LogApi::getAppId, reqVo.getAppId())
                .like(StringUtils.hasText(reqVo.getApiName()), LogApi::getApiName, reqVo.getApiName())
                .eq(reqVo.getDir() != null, LogApi::getDir, reqVo.getDir())
                .eq(StringUtils.hasText(reqVo.getSender()), LogApi::getSender, reqVo.getSender())
                .eq(StringUtils.hasText(reqVo.getReceiver()), LogApi::getReceiver, reqVo.getReceiver())
                .eq(reqVo.getSuccess() != null, LogApi::getSuccess, reqVo.getSuccess())
                .eq(StringUtils.hasText(reqVo.getUrl()), LogApi::getUrl, reqVo.getUrl())
                .orderByDesc(LogApi::getCreateDateTime)
                .page(reqVo.toPage());

        return BasePageResVo.of(page, LogApiListResVo.class);
    }


    @SneakyThrows
    public BasePageResVo<LogApiBusinessResVo> log(LogApiBusinessReqVo reqVo) {

        Page<LogApi> page = logApiMapper.lambdaQuery()
                .like(StringUtils.hasText(reqVo.getApiName()), LogApi::getApiName, reqVo.getApiName())
                .eq(StringUtils.hasText(reqVo.getSender()), LogApi::getSender, reqVo.getSender())
                .eq(StringUtils.hasText(reqVo.getReceiver()), LogApi::getReceiver, reqVo.getReceiver())
                .eq(reqVo.getSuccess() != null, LogApi::getSuccess, reqVo.getSuccess())
                .like(StringUtils.hasText(reqVo.getQueryParam()), LogApi::getQueryParam, reqVo.getQueryParam())

                .ge(StringUtils.hasText(reqVo.getStartTime()), LogApi::getCallDateTime, reqVo.getStartTime())
                .le(StringUtils.hasText(reqVo.getEndTime()), LogApi::getCallDateTime, reqVo.getEndTime())

                .orderByDesc(LogApi::getCallDateTime)
                .page(reqVo.toPage());

        return BasePageResVo.of(page, LogApiBusinessResVo.class);
    }

    @SneakyThrows
    public LogApiDetailResVo detailSan(BaseIdReqVo reqVo) {

        LogApi logApi = logApiMapper.selectById(reqVo.getId());

        String requestPath = logApi.getRequestPath();

        File file = new File(requestPath);
        if (!file.exists()) {
            throw SyExceptionUtils.e("未找到该日志的报文");
        }
        List<String> strings = FileUtils.readLines(file, "UTF-8");
        LogApiDetailResVo res = new LogApiDetailResVo();
        res.setUrl(logApi.getUrl());
        res.setRequestBody(strings.get(0));
        res.setResponseBody(strings.get(1));

        return res;
    }

    @SneakyThrows
    public void retransmission(BaseIdReqVo reqVo) {
        LogApi logApi = logApiMapper.selectById(reqVo.getId());
        if (!logApi.getReceiver().equals("QMS_SY")) {
            throw SyExceptionUtils.e("该日志不是QMS_SY的日志，不能重传。");
        }
        if (Boolean.TRUE.equals(logApi.getSuccess())) {
            throw SyExceptionUtils.e("该日志已经成功，不能重传。");
        }
        String request = "";
        if(StringUtils.hasText(logApi.getRequestPath())){
            File file = new File(logApi.getRequestPath());
            if (!file.exists()) {
                throw SyExceptionUtils.e("未找到该日志的请求报文");
            } else {
                request = FileUtils.readFileToString(new File(logApi.getRequestPath()));
            }
        }
        if (!StringUtils.hasText(request)) {
            throw SyExceptionUtils.e("日志的请求报文为空");
        }
//        TypeReference object1 = ApsConstant.QMS_PUSH_CLASSTYPE.get(logApi.getApiName());
//        if(Objects.isNull(object1)){
//            throw SyExceptionUtils.e("日志类型有误。");
//        }
//        Object object =  objectMapper.readValue(request, object1);
        JsonNode jsonNode = objectMapper.readTree(request); // 强制转换为 JSON 对象，不能直接发送字符串
        mkHttpUtils.postJson(logApi.getReceiver(), logApi.getApiName(), null, jsonNode, consumer);
    }

}
